package net.kindroid.fm;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.RadialGradient;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class FMEntryView extends Activity
{
	/**
	 * whether headset is not insert at oncreate
	 */
	private boolean requireHeadset = false;

	/**
	 * menu for recorder
	 */
	private static final int MENU_RECORDER = 1;

	/**
	 * menu for headset
	 */
	private static final int MENU_HEADSET = MENU_RECORDER + 1;

	/**
	 * menu for headset
	 */
	private static final int MENU_OUTVOICE = MENU_HEADSET + 1;

	/**
	 * menu for tune list
	 */
	private static final int MENU_TUNELIST = MENU_OUTVOICE + 1;

	/**
	 * menu for search
	 */
	private static final int MENU_SEARCH = MENU_TUNELIST + 1;

	/**
	 * channel data
	 */
	private static final String FMRADIO_DATA = "fmradio";

	/**
	 * channel value
	 */
	private static final String CHANNEL_VALUE = "channel_value";

	/**
	 * calibrate view
	 */
	private CalibrateView calibrateView;

	/**
	 * scroll view
	 */
	private ScrollView scrollView;

	/**
	 * channel display area
	 */
	private DigitImageView digitView;

	/**
	 * back fine tuning
	 */
	private ImageView up_low;

	/**
	 * forward fine tuning
	 */
	private ImageView down_low;

	/**
	 * add channel
	 */
	private ImageView add_channel;

	/**
	 * previous channel
	 */
	private ImageView up_channel;

	/**
	 * play
	 */
	private ImageView play;

	/**
	 * next Channel
	 */
	private ImageView down_channel;

	/**
	 * screen display
	 */
	private LinearLayout display;

	/**
	 * title layout
	 */
	private RelativeLayout title_layout;

	/**
	 * calibrateView layout
	 */
	private LinearLayout calibrateView_layout;
	/**
	 * previous channel layout
	 */
	private LinearLayout up_channel_layout;

	/**
	 * play channel layout
	 */
	private LinearLayout play_layout;

	/**
	 * next channel layout
	 */
	private LinearLayout down_channel_layout;

	/**
	 * scroll and low layout
	 */
	private LinearLayout scroll_low_layout;

	/**
	 * scrollView layout
	 */
	private LinearLayout scrollView_layout;

	/**
	 * up low layout
	 */
	private LinearLayout up_low_layout;

	/**
	 * down low layout
	 */
	private LinearLayout down_low_layout;

	/**
	 * screen width
	 */
	private int screenWidth;

	/**
	 * screen height
	 */
	private int screenHeight;

	/**
	 * size
	 */
	private int size;

	/**
	 * delete dialog
	 */
	private MyDialog deleteConfirmDialog = null;

	/**
	 * search channel dialog
	 */
	private MyDialog searchChannelDialog = null;

	/**
	 * add channel dialog
	 */
	private MyDialog addChannelDialog = null;

	/**
	 * is scrolling
	 */
	private boolean isScrolling = true;

	/**
	 * is out voice
	 */
	public static boolean isOutVoice = false;

	/**
	 * cancel search
	 */
	private boolean isSearchCancel = false;

	/**
	 * auto search done
	 */
	private final static int AUTO_SEARCH_DONE = 1;
	/**
	 * move left
	 */
	private static final int DO_SCROLL_LEFT = AUTO_SEARCH_DONE + 1;

	/**
	 * move right
	 */
	private static final int DO_SCROLL_RIGHT = DO_SCROLL_LEFT + 1;

	/**
	 * move right
	 */
	private static final int DO_SCROLL_STOP = DO_SCROLL_RIGHT + 1;

	/**
	 * move right
	 */
	private static final int SEARCH_STATION = DO_SCROLL_STOP + 1;

	/**
	 * channel changed
	 */
	private static final int CHANNEL_CHANGED = SEARCH_STATION + 1;

	private static int SPACE = 700;
	private static final int GAP = 10;
	private int offsetX = 4;
	private int touch_down_x_final = 0;
	private int touch_down_x = 0;
	private int time_delay = 10;
	private long touch_down = 0;
	private boolean isUp = false;
	private boolean isDown = false;
	private boolean isTouchMove = false;

	/**
	 * speed
	 */
	private static final int move_speed = 120;

	/**
	 * total moves
	 */
	private int total_moves = 0;

	/**
	 * progress bar
	 */
	private ProgressBar progressBar;

	/**
	 * is list activity
	 */
	private boolean isListActivity = false;

	/**
	 * wake lock
	 */
	private WakeLock wakeLock = null;

	/**
	 * power manager
	 */
	private PowerManager pm = null;

	/**
	 * show toast
	 */
	private Toast toast = null;

	private class MyHanndler extends Handler
	{
		public MyHanndler(Looper mainLooper)
		{
			super(mainLooper);
		}

		@Override
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
				case AUTO_SEARCH_DONE:
				{
					if (progressBar != null)
					{
						progressBar.setProgress(205);
					}

					SharedPreferences settings = FMEntryView.this.getSharedPreferences(FMRADIO_DATA, 0);
					int current = settings.getInt(CHANNEL_VALUE, 1017);
					if (digitView != null)
					{
						try
						{
							if (mFMService != null && !mFMService.isOpen())
							{
								mFMService.openFM();
								play.setBackgroundResource(R.drawable.stop);
								setEnabled(true);
							}
						} catch (RemoteException e)
						{
						}
						setVolume();
						setChannelToPlay(current);
					}

					try
					{
						if (searchChannelDialog != null && searchChannelDialog.isShowing())
						{
							searchChannelDialog.dismiss();
							searchChannelDialog = null;
							Toast.makeText(FMEntryView.this, FMEntryView.this.getString(R.string.auto_search_done, getChannelNum()), Toast.LENGTH_SHORT).show();
						}
					} catch (Throwable e)
					{
					}
					if (wakeLock != null)
					{
						wakeLock.release();
						wakeLock = null;
					}
					break;
				}
				case DO_SCROLL_LEFT:
				{
					if (digitView.getChannel() > 875 && isScrolling)
					{
						if (time_delay % 3 == 0)
						{
							minusCurrentChannelByGap(1);
						}
						scrollView.offsetX -= offsetX;
						scrollView.invalidate();
					}
					break;
				}
				case DO_SCROLL_RIGHT:
				{
					if (digitView.getChannel() < 1080 && isScrolling)
					{
						if (time_delay % 3 == 0)
						{
							plusCurrentChannelByGap(1);
						}
						scrollView.offsetX += offsetX;
						scrollView.invalidate();
					}
					break;
				}
				case DO_SCROLL_STOP:
				{
					if (isScrolling)
					{
						isScrolling = false;
					}
					setChannelToPlay(digitView.getChannel());
					break;
				}
				case CHANNEL_CHANGED:
				{
					int progress = msg.arg2;
					if (digitView != null)
					{
						updateChannelByGap(msg.arg1);
					}
					if (progressBar != null && progress > progressBar.getProgress())
					{
						progressBar.setProgress(progress);
					}
					break;
				}
				case SEARCH_STATION:
				{
					if (mFMService == null)
					{
						if (mHandler != null)
						{
							mHandler.sendEmptyMessageDelayed(SEARCH_STATION, 500);
						}
						break;
					}

					try
					{
						if (!mFMService.isOpen())
						{
							mFMService.openFM();
							setEnabled(true);
						}
					} catch (Exception e1)
					{
					}

					new Thread(new Runnable()
					{
						@Override
						public void run()
						{
							ContentResolver resolver = FMEntryView.this.getContentResolver();
							int start = 875;
							int sq = 875;
							ContentValues values = null;
							boolean first = true;
							boolean searchState = true;

							if (wakeLock != null)
							{
								wakeLock.acquire();
							}

							try
							{
								if (mFMService != null && mFMService.isOpen())
								{
									while (searchState)
									{
										searchState = mFMService.searchStation(start, 1, 0, 0);
										if (!searchState)
										{
											mHandler.sendEmptyMessage(AUTO_SEARCH_DONE);
											break;
										}
										// get the search tune
										sq = mFMService.getCurrentFrequency();
										mHandler.sendMessage(mHandler.obtainMessage(CHANNEL_CHANGED, sq, sq - 875));
										String where = FMInfo.FMTable.TUNE + " = " + sq;
										Cursor cur = null;

										cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
										if (cur != null && cur.getCount() < 1 && sq >= start)
										{
											// insert
											values = new ContentValues();
											values.put(FMInfo.FMTable.TUNE, sq);
											values.put(FMInfo.FMTable.TITLE, "");
											values.put(FMInfo.FMTable.COMMENT, 0);
											resolver.insert(FMInfo.FMTable.CONTENT_URI, values);
										}

										if (cur != null)
										{
											cur.close();
											cur = null;
										}

										if (isSearchCancel)
										{
											mHandler.sendEmptyMessage(AUTO_SEARCH_DONE);
											break;
										}

										// 2 means the channel is added by user
										if (start == 875)
										{
											where = FMInfo.FMTable.TUNE + " < " + sq + " and " + FMInfo.FMTable.COMMENT + " = '0'";
										} else
										{
											where = FMInfo.FMTable.TUNE + " < " + sq + " and " + FMInfo.FMTable.TUNE + " > " + start + " and " + FMInfo.FMTable.COMMENT + " = '0'";
										}
										cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
										if (cur != null && cur.getCount() > 0)
										{
											cur.moveToFirst();
											while (!cur.isAfterLast())
											{
												where = FMInfo.FMTable.TUNE + " = " + cur.getInt(cur.getColumnIndex(FMInfo.FMTable.TUNE));
												resolver.delete(FMInfo.FMTable.CONTENT_URI, where, null);
												cur.moveToNext();
											}
										}

										if (cur != null)
										{
											cur.close();
											cur = null;
										}

										if (first && sq >= 875)
										{
											SharedPreferences settings = FMEntryView.this.getSharedPreferences(FMRADIO_DATA, 0);
											// store preferences
											SharedPreferences.Editor editor = settings.edit();
											editor.putInt(CHANNEL_VALUE, sq);
											editor.commit();
											editor = null;
											settings = null;
											first = false;
										}

										if (start >= sq)
										{
											// 2 means the channel is added by
											// user
											where = FMInfo.FMTable.TUNE + " > " + start + " and " + FMInfo.FMTable.COMMENT + " = '0'";

											cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
											if (cur != null && cur.getCount() > 0)
											{
												cur.moveToFirst();
												while (!cur.isAfterLast())
												{
													where = FMInfo.FMTable.TUNE + " = " + cur.getInt(cur.getColumnIndex(FMInfo.FMTable.TUNE));
													resolver.delete(FMInfo.FMTable.CONTENT_URI, where, null);
													cur.moveToNext();
												}
											}

											if (cur != null)
											{
												cur.close();
												cur = null;
											}

											mHandler.sendEmptyMessage(AUTO_SEARCH_DONE);
											break;
										}

										start = sq;
									}
								}
							} catch (Exception e)
							{
								mHandler.sendEmptyMessage(AUTO_SEARCH_DONE);
							}
						}
					}).start();
					break;
				}
			}
			super.handleMessage(msg);
		}
	}

	/**
	 * handler
	 */
	private MyHanndler mHandler = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		// this.setTheme(android.R.style.Theme_Translucent);
		super.onCreate(savedInstanceState);
		// judge airplane is open
		if (isAirplanemodeOn())
		{
			// give toast information and finish
			finish();
			showToast(R.string.status_airplanemode);
			return;
		}
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		// judge headset is insert
		if (!isWiredHeadsetOn())
		{
			// show dialog inform user insert headset
			Intent intent = new Intent(this, RequireHeadSetView.class);
			this.startActivity(intent);

			requireHeadset = true;
			return;
		} else
		{
			setContentView(R.layout.main);

			// screen width
			Display display = this.getWindow().getWindowManager().getDefaultDisplay();
			if (display != null)
			{
				screenWidth = display.getWidth();
				screenHeight = display.getHeight();
			}
			if (screenWidth > screenHeight)
			{
				size = screenHeight;
			} else
			{
				size = screenWidth;
			}

			findViews();
			setParams();
			addEvents();
			setResources();
			initData();

			pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);

			wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "FM");
		}
	}

	private void initData()
	{
		scrollView.size = screenWidth;
		scrollView.screen_height = screenHeight;
		if (screenWidth == 320)
		{
			scrollView.total_line = 26;
			scrollView.startMargin = 15;
			scrollView.line_margin = 8f;
			scrollView.line_height_matrix = 0.9f;
			scrollView.line_width_matrix = 1f;
			scrollView.scroll_bg_height_matrix = 1.0f;
			scrollView.scroll_bg_width_matrix = 1.0f;
			scrollView.line_margin_top = 12f * screenHeight / 480f;
			offsetX = 3;
			calibrateView.red_line_top_matrix = 2.5f;
			calibrateView.red_line_height_matrix = 1f;
			calibrateView.red_line_margin = 4;
			calibrateView.red_line_height = screenHeight * 0.1f;
			calibrateView.small_digit_margin_top = 12;
			calibrateView.small_digit_text_size = 10;
			calibrateView.margin = 5;
		} else if (screenWidth == 480)
		{
			scrollView.total_line = 41;
			scrollView.startMargin = 15;
			scrollView.line_margin = 8.5f;
			scrollView.line_height_matrix = 0.9f;
			scrollView.line_width_matrix = 1f;
			scrollView.scroll_bg_height_matrix = 1.0f;
			scrollView.scroll_bg_width_matrix = 1.0f;
			scrollView.line_margin_top = 12f * screenHeight / 480f;
			offsetX = 4;
			calibrateView.red_line_top_matrix = 3;
			calibrateView.red_line_height_matrix = 1.075f;
			calibrateView.red_line_margin = 8;
			calibrateView.red_line_height = screenHeight * 0.095f;
			calibrateView.small_digit_margin_top = 15;
			calibrateView.small_digit_text_size = 16;
			calibrateView.margin = 8;
			SPACE = 400;
		}
		scrollView.invalidate();
		calibrateView.screen_width = screenWidth;
		calibrateView.screen_height = screenHeight;
		calibrateView.space = (int) screenWidth / 41;
		calibrateView.invalidate();
	}

	/**
	 * get data from database
	 */
	private synchronized boolean hasData()
	{
		boolean result = false;
		ContentResolver resolver = getContentResolver();
		Cursor cursor = null;

		try
		{
			cursor = resolver.query(FMInfo.FMTable.CONTENT_URI, null, null, null, null);
		} finally
		{
			if (cursor != null && cursor.getCount() > 0)
			{
				result = true;
			}

			if (cursor != null)
			{
				cursor.close();
				cursor = null;
			}
		}
		return result;
	}

	private int getChannelNum()
	{
		int result = 0;
		ContentResolver resolver = getContentResolver();
		Cursor cursor = null;

		try
		{
			cursor = resolver.query(FMInfo.FMTable.CONTENT_URI, null, null, null, null);
		} finally
		{
			if (cursor != null && cursor.getCount() > 0)
			{
				result = cursor.getCount();
			}

			if (cursor != null)
			{
				cursor.close();
				cursor = null;
			}
		}
		return result;
	}

	private void setResources()
	{
		up_channel.setBackgroundResource(R.drawable.preview);
		down_channel.setBackgroundResource(R.drawable.next);
		play.setBackgroundResource(R.drawable.stop);
	}

	private void addEvents()
	{
		scrollView.setOnTouchListener(touchClickLisnener);
		up_channel.setOnTouchListener(touchClickLisnener);
		down_channel.setOnTouchListener(touchClickLisnener);
		play.setOnTouchListener(touchClickLisnener);
		up_channel_layout.setOnTouchListener(touchClickLisnener);
		play_layout.setOnTouchListener(touchClickLisnener);
		down_channel_layout.setOnTouchListener(touchClickLisnener);

		add_channel.setOnClickListener(onClickListener);
		up_low.setOnTouchListener(touchClickLisnener);
		down_low.setOnTouchListener(touchClickLisnener);

		// close receiver
		registerReceiver(headSetReceiver, new IntentFilter(FMService.CLOSE_FM));
		registerReceiver(headSetReceiver, new IntentFilter(FMService.FM_CHANNEL_SWITCH));
		registerReceiver(headSetReceiver, new IntentFilter(FMService.NOTIFY_STATE_CHANGE));
	}

	/**
	 * find views
	 */
	private void findViews()
	{
		title_layout = (RelativeLayout) findViewById(R.id.title_layout);
		display = (LinearLayout) findViewById(R.id.display);
		digitView = (DigitImageView) findViewById(R.id.digitImageView);
		calibrateView_layout = (LinearLayout) findViewById(R.id.calibrateView_layout);
		calibrateView = (CalibrateView) findViewById(R.id.calibrateView);
		up_low_layout = (LinearLayout) findViewById(R.id.up_channel_layout);
		scroll_low_layout = (LinearLayout) findViewById(R.id.scroll_low_layout);
		scrollView_layout = (LinearLayout) findViewById(R.id.scrollView_layout);
		down_low_layout = (LinearLayout) findViewById(R.id.down_channel_layout);
		scrollView = (ScrollView) findViewById(R.id.scrollView);
		add_channel = (ImageView) findViewById(R.id.add_channel);
		up_low = (ImageView) findViewById(R.id.imgBtn_up_low);
		down_low = (ImageView) findViewById(R.id.imgBtn_down_low);
		up_channel = (ImageView) findViewById(R.id.imgBtn_up_channel);
		down_channel = (ImageView) findViewById(R.id.imgBtn_down_channel);
		play = (ImageView) findViewById(R.id.imgBtn_play);
		up_channel_layout = (LinearLayout) findViewById(R.id.up_channel_layout);
		play_layout = (LinearLayout) findViewById(R.id.play_layout);
		down_channel_layout = (LinearLayout) findViewById(R.id.down_channel_layout);
	}

	private void setParams()
	{
		LayoutParams params = null;
		params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, (int) (screenHeight * 0.1015));
		title_layout.setLayoutParams(params);
		title_layout.setGravity(Gravity.CENTER);

		params = null;
		params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (screenHeight * 0.4375));
		display.setLayoutParams(params);
		display.setGravity(Gravity.CENTER);

		if (screenWidth == 320)
		{
			params = null;
			params = new LinearLayout.LayoutParams((int) (screenWidth * 0.75), (int) (screenHeight * 0.075));
			scrollView.setLayoutParams(params);

			params = null;
			LinearLayout.LayoutParams marginPara = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (screenHeight * 0.125));
			marginPara.topMargin = 2;
			calibrateView_layout.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, (LinearLayout.LayoutParams.WRAP_CONTENT));
			marginPara.topMargin = (int) (screenHeight * 0.015);
			marginPara.bottomMargin = (int) (screenHeight * 0.015);
			scroll_low_layout.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, (LinearLayout.LayoutParams.WRAP_CONTENT));
			marginPara.leftMargin = 7;
			marginPara.rightMargin = 7;
			marginPara.topMargin = 3;
			up_low.setLayoutParams(marginPara);
			down_low.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams((int) (screenWidth * 0.3333), (int) (screenHeight * 0.1625));
			marginPara.topMargin = (int) (screenHeight * 0.0185);
			up_channel_layout.setLayoutParams(marginPara);
			play_layout.setLayoutParams(marginPara);
			down_channel_layout.setLayoutParams(marginPara);
			params = null;
		} else if (screenWidth == 480)
		{
			params = null;
			params = new LinearLayout.LayoutParams((int) (screenWidth * 0.75), (int) (screenHeight * 0.085));
			scrollView.setLayoutParams(params);

			params = null;
			LinearLayout.LayoutParams marginPara = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (screenHeight * 0.12));
			marginPara.topMargin = 8;
			calibrateView_layout.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, (LinearLayout.LayoutParams.WRAP_CONTENT));
			marginPara.topMargin = 12;
			marginPara.bottomMargin = 6;
			scroll_low_layout.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams((int) (screenWidth * 0.1005), 49);
			marginPara.leftMargin = (int) (screenHeight * 0.007);
			marginPara.rightMargin = (int) (screenHeight * 0.007);
			marginPara.topMargin = 5;
			up_low.setLayoutParams(marginPara);
			down_low.setLayoutParams(marginPara);

			marginPara = null;
			marginPara = new LinearLayout.LayoutParams((int) (screenWidth * 0.3333), (int) (screenHeight * 0.1625));
			marginPara.topMargin = 5;
			up_channel_layout.setLayoutParams(marginPara);
			play_layout.setLayoutParams(marginPara);
			down_channel_layout.setLayoutParams(marginPara);
			params = null;
		}
	}

	/**
	 * set channel text and red line and channel to play
	 * 
	 * @param updateChannel
	 */
	private void updateChannel(int channel)
	{
		if (channel != digitView.getChannel())
		{
			setChannelToPlay(channel);
		}
	}

	/**
	 * set channel text and red line by gap
	 * 
	 * @param updateChannel
	 */
	private void updateChannelByGap(int channel)
	{
		if (channel != digitView.getChannel())
		{
			digitView.setChannel(channel);
			updateRedLine(channel);
		}
	}

	/**
	 * set play channel
	 * 
	 * @param channel
	 */
	private void setChannelToPlay(int channel)
	{
		if (mFMService != null)
		{
			try
			{
				if (mFMService.setCurrentFrequency(channel) > 0)
				{
					digitView.setChannel(channel);
					updateRedLine(channel);
				}
			} catch (RemoteException e)
			{
			}
		}
	}

	/**
	 * update red line
	 * 
	 * @param channel
	 */
	private void updateRedLine(int channel)
	{
		calibrateView.red_line_X = (float) ((channel - 875) * (calibrateView.space / 5.0f) + calibrateView.left_margin);
		calibrateView.invalidate();
	}

	/**
	 * plus current channel text and red line
	 * 
	 * @param minusValues
	 */
	private void plusCurrentChannel(int addValues)
	{
		int values = digitView.getChannel() + addValues;
		if (values <= 1080)
		{
			updateChannel(values);
		}
	}

	/**
	 * plus current channel text and red line
	 * 
	 * @param minusValues
	 */
	private void plusCurrentChannelByGap(int addValues)
	{
		int values = digitView.getChannel() + addValues;
		if (values <= 1080)
		{
			updateChannelByGap(values);
		}
	}

	/**
	 * minus current channel text and red line
	 * 
	 * @param minusValues
	 */
	private void minusCurrentChannel(int minusValues)
	{
		int values = digitView.getChannel() - minusValues;
		if (values >= 875)
		{
			updateChannel(values);
		}
	}

	/**
	 * minus current channel text and red line
	 * 
	 * @param minusValues
	 */
	private void minusCurrentChannelByGap(int minusValues)
	{
		int values = digitView.getChannel() - minusValues;
		if (values >= 875)
		{
			updateChannelByGap(values);
		}
	}

	/**
	 * onClickListener
	 */
	private OnClickListener onClickListener = new android.view.View.OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			isScrolling = false;
			if (view.getId() == R.id.add_channel)
			{
				// add channel click
				showAddChannelDialog();
			}
		}
	};

	/**
	 * View Touch
	 */
	private OnTouchListener touchClickLisnener = new android.view.View.OnTouchListener()
	{
		public boolean onTouch(View view, MotionEvent event)
		{
			if (view.getId() == R.id.scrollView)
			{
				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					touch_down = System.currentTimeMillis();
					touch_down_x = (int) event.getRawX();
					touch_down_x_final = touch_down_x;
					isScrolling = false;
					time_delay = 10;
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					if (Math.abs(event.getRawX() - touch_down_x) >= 1)
					{
						isScrolling = true;
						// scroll right
						if (touch_down_x < (int) event.getRawX())
						{
							if (System.currentTimeMillis() - touch_down > 50)
							{
								touchRight((int) event.getRawX());
							}
							touch_down_x = (int) event.getRawX();
						} else if (touch_down_x > (int) event.getRawX())
						{
							// scroll left
							touchLeft((int) event.getRawX());
							touch_down_x = (int) event.getRawX();
						}
					}
					play_layout.setBackgroundResource(R.drawable.button_normal);
					up_channel_layout.setBackgroundResource(R.drawable.button_normal);
					down_channel_layout.setBackgroundResource(R.drawable.button_normal);
					up_low.setBackgroundResource(R.drawable.up_low);
					down_low.setBackgroundResource(R.drawable.down_low);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (System.currentTimeMillis() - touch_down <= SPACE && Math.abs(event.getRawX() - touch_down_x_final) > GAP)
					{
						total_moves = (int) (Math.abs(event.getRawX() - touch_down_x_final) * move_speed / (System.currentTimeMillis() - touch_down));
						// scroll right
						if ((int) event.getRawX() - touch_down_x_final > 0)
						{
							new Thread(new Runnable()
							{
								@Override
								public void run()
								{
									for (int i = 0; i < total_moves; i++)
									{
										if (!isScrolling)
										{
											mHandler.sendEmptyMessage(DO_SCROLL_STOP);
											break;
										}
										mHandler.sendEmptyMessage(DO_SCROLL_RIGHT);
										try
										{
											Thread.sleep(time_delay);
											time_delay += 1;
										} catch (InterruptedException e)
										{
										}
									}
									mHandler.sendEmptyMessage(DO_SCROLL_STOP);
								}
							}).start();

						} else
						// scroll left
						{
							new Thread(new Runnable()
							{
								@Override
								public void run()
								{
									for (int i = 0; i < total_moves; i++)
									{
										if (!isScrolling)
										{
											mHandler.sendEmptyMessage(DO_SCROLL_STOP);
											break;
										}
										mHandler.sendEmptyMessage(DO_SCROLL_LEFT);
										try
										{
											Thread.sleep(time_delay);
											time_delay += 1;
										} catch (InterruptedException e)
										{
										}
									}
									mHandler.sendEmptyMessage(DO_SCROLL_STOP);
								}
							}).start();
						}
					} else
					{
						setChannelToPlay(digitView.getChannel());
					}
				}
			} else if (view.getId() == R.id.imgBtn_up_channel || view.getId() == R.id.up_channel_layout)
			{
				int size = 0;
				if (screenWidth > screenHeight)
				{
					size = screenWidth;
				} else
				{
					size = screenHeight;
				}

				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					up_channel_layout.setBackgroundResource(R.drawable.button_press);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (event.getRawY() >= size - up_channel_layout.getHeight() && event.getRawX() <= up_channel_layout.getWidth())
					{
						// previous channel click
						openChannel(digitView.getChannel(), true);

						up_channel_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = false;
					}
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					if (event.getRawY() < size - up_channel_layout.getHeight() || event.getRawX() > up_channel_layout.getWidth())
					{
						up_channel_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = true;
					}
				}
			} else if (view.getId() == R.id.imgBtn_play || view.getId() == R.id.play_layout)
			{
				int size = 0;
				if (screenWidth > screenHeight)
				{
					size = screenWidth;
				} else
				{
					size = screenHeight;
				}

				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					play_layout.setBackgroundResource(R.drawable.button_press);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (event.getRawY() >= size - up_channel_layout.getHeight() && event.getRawX() <= up_channel_layout.getWidth() * 2 && event.getRawX() >= up_channel_layout.getWidth())
					{
						if (FMService.isCallState)
						{
							showToast(R.string.no_play);
							play_layout.setBackgroundResource(R.drawable.button_normal);
							return true;
						}
						isScrolling = false;
						// play button click
						if (mFMService != null)
						{
							try
							{
								if (mFMService.isOpen() && !FMService.isMusicVolumeFocus)
								{
									closeVolume();
									try
									{
										Thread.sleep(50);
									} catch (InterruptedException e)
									{
									}
									mFMService.closeFM();
									play.setBackgroundResource(R.drawable.play);
									setEnabled(false);
								} else
								{
									mFMService.openFM();
									setChannelToPlay(digitView.getChannel());
									setVolume();
									play.setBackgroundResource(R.drawable.stop);
									setEnabled(true);
									FMService.isMusicVolumeFocus = false;
								}
							} catch (RemoteException e)
							{
							}
						}
						play_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = false;
					}
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					if (event.getRawY() < size - up_channel_layout.getHeight() || event.getRawX() < up_channel_layout.getWidth() || event.getRawX() > up_channel_layout.getWidth() * 2)
					{
						play_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = true;
					}
				}
			} else if (view.getId() == R.id.imgBtn_down_channel || view.getId() == R.id.down_channel_layout)
			{
				int size = 0;
				if (screenWidth > screenHeight)
				{
					size = screenWidth;
				} else
				{
					size = screenHeight;
				}

				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					down_channel_layout.setBackgroundResource(R.drawable.button_press);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (event.getRawY() >= size - up_channel_layout.getHeight() && event.getRawX() >= up_channel_layout.getWidth() * 2)
					{
						// next channel click
						openChannel(digitView.getChannel(), false);

						down_channel_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = false;
					}
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					if (event.getRawY() < size - up_channel_layout.getHeight() || event.getRawX() < up_channel_layout.getWidth() * 2)
					{
						down_channel_layout.setBackgroundResource(R.drawable.button_normal);
						isTouchMove = true;
					}
				}
			} else if (view.getId() == R.id.imgBtn_up_low)
			{
				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					isScrolling = false;
					isUp = true;
					up_low.setBackgroundResource(R.drawable.up_low_press);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (isUp)
					{
						uplow();
					}
					up_low.setBackgroundResource(R.drawable.up_low);
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					// if ((int) event.getRawX() > 40 || (int) event.getRawX() <
					// 0 || (int) event.getRawY() > 330 || (int) event.getRawY()
					// < 290)
					// {
					// isUp = false;
					// up_low.setBackgroundResource(R.drawable.up_low);
					// }
				}
			} else if (view.getId() == R.id.imgBtn_down_low)
			{
				if (event.getAction() == MotionEvent.ACTION_DOWN)
				{
					isScrolling = false;
					isDown = true;
					down_low.setBackgroundResource(R.drawable.down_low_press);
				} else if (event.getAction() == MotionEvent.ACTION_UP)
				{
					if (isDown)
					{
						downLow();
					}
					down_low.setBackgroundResource(R.drawable.down_low);
				} else if (event.getAction() == MotionEvent.ACTION_MOVE)
				{
					// if ((int) event.getRawX() < 200 || (int) event.getRawX()
					// > 240 || (int) event.getRawY() > 330 || (int)
					// event.getRawY() < 290)
					// {
					// isDown = false;
					// down_low.setBackgroundResource(R.drawable.down_low);
					// }
				}
			}
			if (event.getAction() == MotionEvent.ACTION_UP && isTouchMove)
			{
				try
				{
					if (mFMService.getCurrentFrequency() != digitView.getChannel())
					{
						setChannelToPlay(digitView.getChannel());
					}
				} catch (Exception e)
				{
				}
			}
			return true;
		}

		/**
		 * down low
		 */
		private void downLow()
		{
			if (calibrateView.red_line_X < size - calibrateView.left_margin)
			{
				plusCurrentChannel(1);
			}
		}

		/**
		 * up low
		 */
		private void uplow()
		{
			if (calibrateView.red_line_X > calibrateView.left_margin)
			{
				minusCurrentChannel(1);
			}
		}

		/**
		 * red_line_X 100KB isUpChannel is previous channel
		 */
		private void openChannel(int channel, boolean isUpChannel)
		{
			int tune = 0;
			isScrolling = false;
			if (isUpChannel)
			{
				String where = FMInfo.FMTable.TUNE + " < " + channel;
				// channel list
				String order = FMInfo.FMTable.TUNE + " ASC";
				ContentResolver resolver = FMEntryView.this.getContentResolver();
				Cursor cur = null;

				cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, order);
				if (cur != null && cur.getCount() > 0)
				{
					cur.moveToLast();
					tune = cur.getInt(cur.getColumnIndex("tune"));
					cur.close();
					cur = null;
					updateChannel(tune);
				} else
				{
					// cycle play channel
					cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, null, null, order);
					if (cur != null && cur.getCount() > 0)
					{
						cur.moveToLast();
						tune = cur.getInt(cur.getColumnIndex("tune"));
						cur.close();
						cur = null;
						updateChannel(tune);
					}
				}
				if (cur != null)
				{
					cur.close();
					cur = null;
				}
			} else
			{
				String where = FMInfo.FMTable.TUNE + " > " + channel;
				// channel list
				String order = FMInfo.FMTable.TUNE + " ASC";
				ContentResolver resolver = FMEntryView.this.getContentResolver();
				Cursor cur = null;

				cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, order);
				if (cur != null && cur.getCount() > 0)
				{
					cur.moveToFirst();
					tune = cur.getInt(cur.getColumnIndex("tune"));
					cur.close();
					cur = null;
					updateChannel(tune);
				} else
				{
					// cycle play channel
					cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, null, null, order);
					if (cur != null && cur.getCount() > 0)
					{
						cur.moveToFirst();
						tune = cur.getInt(cur.getColumnIndex("tune"));
						cur.close();
						cur = null;
						updateChannel(tune);
					}
				}
				if (cur != null)
				{
					cur.close();
					cur = null;
				}
			}
		}

		/**
		 * touch right
		 * 
		 * @param intRawX
		 */
		private void touchRight(int intRawX)
		{
			if (digitView.getChannel() < 1080)
			{
				plusCurrentChannelByGap(1);
				scrollView.offsetX += offsetX;
				scrollView.invalidate();
			}
		}

		/**
		 * touch left
		 * 
		 * @param intRawX
		 */
		private void touchLeft(int intRawX)
		{
			if (digitView.getChannel() > 875)
			{
				minusCurrentChannelByGap(1);
				scrollView.offsetX -= offsetX;
				scrollView.invalidate();
			}
		}
	};

	private void setEnabled(boolean isEnable)
	{
		digitView.setEnabled(isEnable);
		scrollView.setEnabled(isEnable);
		add_channel.setEnabled(isEnable);
		up_low.setEnabled(isEnable);
		down_low.setEnabled(isEnable);
		up_channel_layout.setEnabled(isEnable);
		down_channel_layout.setEnabled(isEnable);
		up_channel.setEnabled(isEnable);
		down_channel.setEnabled(isEnable);
		if (isEnable)
		{
			up_channel.setBackgroundResource(R.drawable.preview);
			down_channel.setBackgroundResource(R.drawable.next);
			up_channel_layout.setBackgroundResource(R.drawable.button_normal);
			down_channel_layout.setBackgroundResource(R.drawable.button_normal);
			up_low.setBackgroundResource(R.drawable.up_low);
			down_low.setBackgroundResource(R.drawable.down_low);
		} else
		{
			up_channel.setBackgroundResource(R.drawable.preview_invalid);
			down_channel.setBackgroundResource(R.drawable.next_invalid);
			up_low.setBackgroundResource(R.drawable.up_low_invalid);
			down_low.setBackgroundResource(R.drawable.down_low_invalid);
		}
	}

	@Override
	protected void onRestart()
	{
		super.onRestart();
	}

	@Override
	protected void onStart()
	{
		super.onStart();
	}

	@Override
	protected void onResume()
	{
		isListActivity = false;
		FMService.isFMState = true;
		FMService.isActivityFocus = true;
		if (mHandler == null)
		{
			if (Looper.getMainLooper() != null)
			{
				mHandler = new MyHanndler(Looper.getMainLooper());
			} else
			{
				mHandler = new MyHanndler(Looper.myLooper());
			}
		}

		if (mFMService == null)
		{
			try
			{
				// start server
				this.startService(new Intent("net.kindroid.aidl.service.IFMService"));
				bindService(new Intent("net.kindroid.aidl.service.IFMService"), serviceConnection, Context.BIND_AUTO_CREATE);
			} catch (Exception e)
			{
			}
		}
		if (FMService.isMusicVolumeFocus || isCallState())
		{
			play.setBackgroundResource(R.drawable.play);
			setEnabled(false);
		} else
		{
			try
			{
				if (mFMService != null && !mFMService.isOpen())
				{
					play.setBackgroundResource(R.drawable.play);
					setEnabled(false);
				} else
				{
					play.setBackgroundResource(R.drawable.stop);
					setEnabled(true);
				}
			} catch (Exception e)
			{
			}
		}
		super.onResume();
		if (!hasData())
		{
			showSearchDialog();
		}
	}

	@Override
	protected void onPause()
	{
		FMService.isActivityFocus = false;
		super.onPause();
		if (isListActivity)
		{
			return;
		}
		try
		{
			if (mFMService != null && !mFMService.isOpen() || !isWiredHeadsetOn())
			{
				FMService.isFMState = false;
				if (digitView != null)
				{
					SharedPreferences settings = this.getSharedPreferences(FMRADIO_DATA, 0);
					// store preferences
					SharedPreferences.Editor editor = settings.edit();
					editor.putInt(CHANNEL_VALUE, digitView.getChannel());
					editor.commit();
					editor = null;
					settings = null;
					up_channel_layout.setBackgroundResource(R.drawable.button_normal);
					down_channel_layout.setBackgroundResource(R.drawable.button_normal);
					play_layout.setBackgroundResource(R.drawable.button_normal);
				}
				if (mFMService != null && mFMService.isOpen())
				{
					mFMService.closeFM();
				}

				try
				{
					this.stopService(new Intent("net.kindroid.aidl.service.IFMService"));
					this.unbindService(serviceConnection);
					unregisterReceiver(headSetReceiver);
				} catch (Exception e)
				{
				}
				mFMService = null;

				this.finish();
			} else if (mFMService == null)
			{
				unregisterReceiver(headSetReceiver);
				this.finish();
			}
		} catch (Exception e)
		{
		}
	}

	@Override
	protected void onStop()
	{
		if (deleteConfirmDialog != null && deleteConfirmDialog.isShowing())
		{
			deleteConfirmDialog.dismiss();
			addChannelDialog = null;
		}
		if (addChannelDialog != null && addChannelDialog.isShowing())
		{
			addChannelDialog.dismiss();
			addChannelDialog = null;
		}

		super.onStop();
	}

	@Override
	protected void onDestroy()
	{
		super.onDestroy();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		switch (resultCode)
		{
			case RESULT_OK:
			{
				if (data != null)
				{
					int tune = data.getIntExtra("list_tune", 875);
					if (tune >= 875)
					{
						try
						{
							if (!mFMService.isOpen())
							{
								mFMService.openFM();
								setChannelToPlay(digitView.getChannel());
								setVolume();
								play.setBackgroundResource(R.drawable.stop);
								setEnabled(true);
							}
						} catch (RemoteException e)
						{
						}
						updateChannel(tune);
					} else
					{
						showSearchDialog();
					}
				}
				break;
			}
			default:
				break;
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			if (digitView != null)
			{
				SharedPreferences settings = this.getSharedPreferences(FMRADIO_DATA, 0);
				// store preferences
				SharedPreferences.Editor editor = settings.edit();
				editor.putInt(CHANNEL_VALUE, digitView.getChannel());
				editor.commit();
				editor = null;
				settings = null;
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
			case MENU_RECORDER:
			{
				break;
			}
			case MENU_HEADSET:
			{
				setHeadset();
				break;
			}
			case MENU_OUTVOICE:
			{
				setOutvoice();
				break;
			}
			case MENU_TUNELIST:
			{
				isListActivity = true;
				Intent intent = new Intent();
				intent.putExtra("currentChannel", digitView.getChannel());
				try
				{
					intent.putExtra("isPlaying", mFMService.isOpen() ? true : false);
				} catch (RemoteException e)
				{
				}
				intent.setClass(FMEntryView.this, ChannelList.class);
				startActivityForResult(intent, 0);
				return true;
			}
			case MENU_SEARCH:
			{
				showDeleteConfirmDialog();
				break;
			}
		}
		return super.onOptionsItemSelected(item);
	}

	private void setHeadset()
	{
		isOutVoice = false;
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_FM);
		intent.putExtra("state", 1);
		intent.putExtra("speaker", 0);
		this.sendBroadcast(intent);
	}

	private void setOutvoice()
	{
		isOutVoice = true;
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_FM);
		intent.putExtra("state", 1);
		intent.putExtra("speaker", 1);
		this.sendBroadcast(intent);
	}

	private void showToast(int resId)
	{
		if (toast != null)
		{
			toast.setText(resId);
			toast.show();
		} else
		{
			toast = Toast.makeText(FMEntryView.this, resId, Toast.LENGTH_SHORT);
			toast.show();
		}
	}

	/**
	 * add channel dialog
	 */
	private void showAddChannelDialog()
	{
		addChannelDialog = new MyDialog(this);
		LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.edit_channel_layout, null);
		int size = 0;
		if (screenWidth > screenHeight)
		{
			size = screenWidth;
		} else
		{
			size = screenHeight;
		}

		// set dialog size
		addChannelDialog.setDialogSize((int) (size * 0.55), (int) (size * 0.27));
		addChannelDialog.setMyContentView(layout);
		addChannelDialog.show();

		ImageButton title_icon = (ImageButton) layout.findViewById(R.id.edit_title_icon);
		TextView title_name = (TextView) layout.findViewById(R.id.edit_title_text);

		TextView tune_name = (TextView) layout.findViewById(R.id.edit_content_tune_title);
		TextView tune_value = (TextView) layout.findViewById(R.id.edit_content_tune_name);

		TextView tune_title = (TextView) layout.findViewById(R.id.edit_content_name_title);
		final EditText input_title = (EditText) layout.findViewById(R.id.edit_content_name_input);

		Button ok = (Button) layout.findViewById(R.id.edit_button_Ok);
		Button cancel = (Button) layout.findViewById(R.id.edit_button_Cancel);

		final int tune = (int) (digitView.getChannel());

		ContentResolver resolver = getContentResolver();
		String where = FMInfo.FMTable.TUNE + " = " + tune;
		Cursor cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
		String channel_Name = "";
		if (cur != null && cur.moveToFirst())
		{
			channel_Name = cur.getString(cur.getColumnIndex(FMInfo.FMTable.TITLE));
		}
		if (cur != null)
		{
			cur.close();
			cur = null;
		}
		int textSize = 18;
		title_icon.setBackgroundResource(R.drawable.delete_confirm);
		title_name.setTextSize(textSize);
		title_name.setTextColor(Color.WHITE);
		title_name.setText(this.getText(R.string.edit_channel));

		tune_name.setTextSize(textSize);
		tune_name.setTextColor(Color.WHITE);
		tune_name.setText(this.getText(R.string.channel));
		tune_value.setTextSize(textSize);
		tune_value.setTextColor(Color.WHITE);
		tune_value.setText(tune / 10.0f + " MHZ");

		tune_title.setTextSize(textSize);
		tune_title.setTextColor(Color.WHITE);
		tune_title.setText(this.getText(R.string.title));

		input_title.setTextSize(textSize);
		input_title.setTextColor(Color.BLACK);
		input_title.setText(channel_Name);
		input_title.setSelection(input_title.getText().length());

		ok.setText(R.string.ok);
		cancel.setText(R.string.cancel);

		ok.setTextColor(Color.BLACK);
		cancel.setTextColor(Color.BLACK);

		ok.setTextSize(textSize);
		cancel.setTextSize(textSize);

		ok.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				ContentResolver resolver = getContentResolver();
				String where = FMInfo.FMTable.TUNE + " = " + tune;
				String title = input_title.getText().toString().trim();
				ContentValues values = new ContentValues();
				Cursor cur = null;

				if (title == "" || title.equals(""))
				{
					showToast(R.string.title_hint);
					return;
				}

				cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
				if (cur != null && cur.getCount() > 0)
				{
					cur.close();
					cur = null;
					where = FMInfo.FMTable.TUNE + " = " + tune + " and " + FMInfo.FMTable.TITLE + " = '" + title + "'";

					cur = resolver.query(FMInfo.FMTable.CONTENT_URI, null, where, null, null);
					if (cur != null && cur.getCount() > 0)
					{
						// no update
						showToast(R.string.channel_already_exists);
						cur.close();
						cur = null;
					} else
					{
						// update
						values.put(FMInfo.FMTable.TITLE, title);
						if (title != null && !title.equals(""))
						{
							// 1 means the title is not null
							values.put(FMInfo.FMTable.COMMENT, 1);
						}
						where = FMInfo.FMTable.TUNE + " = " + tune;
						int status = resolver.update(FMInfo.FMTable.CONTENT_URI, values, where, null);

						if (status > 0)
						{
							showToast(R.string.edit_success);
						} else
						{
							showToast(R.string.edit_error);
						}
					}
				} else
				{
					// insert
					values.put(FMInfo.FMTable.TUNE, tune);
					values.put(FMInfo.FMTable.TITLE, title);
					// 2 means the channel is added by user
					values.put(FMInfo.FMTable.COMMENT, 2);
					Uri status = resolver.insert(FMInfo.FMTable.CONTENT_URI, values);
					if (status != null)
					{
						showToast(R.string.add_success);
					} else
					{
						showToast(R.string.add_error);
					}
				}

				if (cur != null)
				{
					cur.close();
					cur = null;
				}

				if (addChannelDialog != null)
				{
					addChannelDialog.dismiss();
					addChannelDialog = null;
				}
			}
		});

		cancel.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				if (addChannelDialog != null)
				{
					addChannelDialog.dismiss();
					addChannelDialog = null;
				}
			}
		});
	}

	/**
	 * sure delete
	 */
	private void showDeleteConfirmDialog()
	{
		deleteConfirmDialog = new MyDialog(this);
		final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.delete_comform_layout, null);
		int size = 0;
		if (screenWidth > screenHeight)
		{
			size = screenWidth;
		} else
		{
			size = screenHeight;
		}

		// set dialog size
		deleteConfirmDialog.setDialogSize((int) (size * 0.55), (int) (size * 0.27));
		deleteConfirmDialog.setMyContentView(layout);
		deleteConfirmDialog.show();

		ImageButton title_icon = (ImageButton) layout.findViewById(R.id.delete_title_icon);
		final TextView title_name = (TextView) layout.findViewById(R.id.delete_title_text);
		final TextView content = (TextView) layout.findViewById(R.id.delete_content_text);

		LinearLayout bottom_layout = (LinearLayout) layout.findViewById(R.id.delete_bottom_layout);
		bottom_layout.setBackgroundColor(Color.WHITE);
		final Button ok = (Button) layout.findViewById(R.id.delete_button_Ok);
		final Button cancel = (Button) layout.findViewById(R.id.delete_button_Cancel);

		title_icon.setBackgroundResource(R.drawable.delete_confirm);

		int textSize = 18;
		title_name.setTextSize(textSize);
		title_name.setTextColor(Color.WHITE);
		title_name.setText(R.string.search_confirm_title);

		content.setTextSize(textSize);
		content.setTextColor(Color.WHITE);
		content.setText(R.string.search_delete_confirm_content);

		ok.setText(R.string.ok);
		ok.setTextColor(Color.BLACK);
		ok.setTextSize(textSize);
		ok.setOnClickListener(new android.view.View.OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				isSearchCancel = false;
				deleteConfirmDialog.dismiss();
				deleteConfirmDialog = null;

				showSearchDialog();
			}
		});

		cancel.setText(R.string.cancel);
		cancel.setTextColor(Color.BLACK);
		cancel.setTextSize(textSize);
		cancel.setOnClickListener(new android.view.View.OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				if (deleteConfirmDialog != null && deleteConfirmDialog.isShowing())
				{
					deleteConfirmDialog.dismiss();
					deleteConfirmDialog = null;
				}
			}
		});
	}

	/**
	 * search dialog
	 */
	private void showSearchDialog()
	{
		if (searchChannelDialog != null)
		{
			return;
		}
		searchChannelDialog = new MyDialog(this);
		final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.delete_comform_layout, null);
		int size = 0;
		if (screenWidth > screenHeight)
		{
			size = screenWidth;
		} else
		{
			size = screenHeight;
		}

		// set dialog size
		searchChannelDialog.setDialogSize((int) (size * 0.55), (int) (size * 0.27));
		searchChannelDialog.setMyContentView(layout);
		searchChannelDialog.show();

		ImageButton title_icon = (ImageButton) layout.findViewById(R.id.delete_title_icon);
		final TextView title_name = (TextView) layout.findViewById(R.id.delete_title_text);

		final TextView content = (TextView) layout.findViewById(R.id.delete_content_text);

		LinearLayout bottom_layout = (LinearLayout) layout.findViewById(R.id.delete_bottom_layout);
		bottom_layout.setBackgroundColor(Color.WHITE);
		final Button ok = (Button) layout.findViewById(R.id.delete_button_Ok);
		final Button cancel = (Button) layout.findViewById(R.id.delete_button_Cancel);
		final ProgressBar cancelProgressBar = (ProgressBar) layout.findViewById(R.id.canceling_process_dialog_progressBar);

		title_icon.setBackgroundResource(R.drawable.delete_confirm);

		progressBar = (ProgressBar) layout.findViewById(R.id.loading_process_dialog_progressBar);
		progressBar.setVisibility(View.VISIBLE);

		int textSize = 18;
		content.setTextSize(textSize);
		content.setTextColor(Color.WHITE);
		content.setText(R.string.search_content);

		title_name.setTextSize(textSize);
		title_name.setTextColor(Color.WHITE);
		title_name.setText(R.string.search_confirm_title);

		ok.setVisibility(View.GONE);

		cancel.setText(R.string.cancel);
		cancel.setTextColor(Color.BLACK);
		cancel.setTextSize(textSize);
		cancel.setOnClickListener(new android.view.View.OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				isSearchCancel = true;
				if (deleteConfirmDialog != null && deleteConfirmDialog.isShowing())
				{
					deleteConfirmDialog.dismiss();
					deleteConfirmDialog = null;
				}
				progressBar.setVisibility(View.GONE);
				cancelProgressBar.setVisibility(View.VISIBLE);
				content.setText(R.string.cancel_search_content);
				cancel.setVisibility(View.GONE);
			}
		});
		searchChannelDialog.setOnKeyListener(new OnKeyListener()
		{
			@Override
			public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event)
			{
				switch (keyCode)
				{
					case KeyEvent.KEYCODE_BACK:
					{
						isSearchCancel = true;
						progressBar.setVisibility(View.GONE);
						cancelProgressBar.setVisibility(View.VISIBLE);
						content.setText(R.string.cancel_search_content);
						cancel.setVisibility(View.GONE);
						break;
					}
				}
				return true;
			}
		});
		if (mFMService != null)
		{
			try
			{
				if (!mFMService.isOpen())
				{
					mFMService.openFM();
					play.setBackgroundResource(R.drawable.stop);
					setEnabled(true);
				}
			} catch (RemoteException e)
			{
			}
		}
		closeVolume();
		if (mHandler != null)
		{
			mHandler.sendEmptyMessage(SEARCH_STATION);
		}
	}

	private void closeVolume()
	{
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_FM);
		intent.putExtra("state", 0);
		intent.putExtra("speaker", 0);
		sendBroadcast(intent);
	}

	private int getMenuIconResource(int res)
	{
		int result = 0;
		switch (res)
		{
			case MENU_RECORDER:
			{
				result = R.drawable.record;
				break;
			}
			case MENU_HEADSET:
			{
				result = R.drawable.headset;
				break;
			}
			case MENU_OUTVOICE:
			{
				result = R.drawable.external;
				break;
			}
			case MENU_TUNELIST:
			{
				result = R.drawable.list;
				break;
			}
			case MENU_SEARCH:
			{
				result = R.drawable.search;
				break;
			}
		}
		return result;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		menu.removeItem(MENU_RECORDER);
		menu.removeItem(MENU_HEADSET);
		menu.removeItem(MENU_OUTVOICE);
		menu.removeItem(MENU_TUNELIST);
		menu.removeItem(MENU_SEARCH);

		// menu.add(0, MENU_RECORDER, 1,
		// R.string.menu_recorder).setIcon(getMenuIconResource(MENU_RECORDER));
		// judge current mode
		if (isOutVoice)
		{
			menu.add(0, MENU_HEADSET, 2, R.string.menu_headset).setIcon(getMenuIconResource(MENU_HEADSET));
		} else
		{
			menu.add(0, MENU_OUTVOICE, 2, R.string.menu_outvoice).setIcon(getMenuIconResource(MENU_OUTVOICE));
		}
		menu.add(0, MENU_TUNELIST, 3, R.string.menu_tunelist).setIcon(getMenuIconResource(MENU_TUNELIST));
		menu.add(0, MENU_SEARCH, 4, R.string.menu_search).setIcon(getMenuIconResource(MENU_SEARCH));

		return super.onPrepareOptionsMenu(menu);
	}

	/**
	 * judge current airplane mode is set on
	 * 
	 * @return
	 */
	private boolean isAirplanemodeOn()
	{
		return Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
	}

	/**
	 * headset listener
	 */
	private final BroadcastReceiver headSetReceiver = new BroadcastReceiver()
	{
		public void onReceive(Context context, Intent intent)
		{
			String action = intent.getAction();
			if (action.equals(FMService.CLOSE_FM))
			{
				if (mFMService != null)
				{
					try
					{
						mFMService.closeFM();
					} catch (Exception e)
					{
					}
					FMEntryView.this.stopService(new Intent("net.kindroid.aidl.service.IFMService"));
					FMEntryView.this.unbindService(serviceConnection);
					try
					{
						unregisterReceiver(headSetReceiver);
					} catch (Exception e)
					{
					}
					mFMService = null;
				}
				FMService.isFMState = false;
				if (intent.getBooleanExtra(FMService.OPEN_DEVICE_ERROR, false))
				{
					Toast.makeText(FMEntryView.this, getText(R.string.open_device_error), Toast.LENGTH_SHORT).show();
				}
				finish();
			} else if (action.equals(FMService.FM_CHANNEL_SWITCH))
			{
				setChannelToPlay(digitView.getChannel());
			} else if (action.equals(FMService.NOTIFY_STATE_CHANGE))
			{
				if (!isCallState() && !FMService.isMusicVolumeFocus)
				{
					play.setBackgroundResource(R.drawable.stop);
					setEnabled(true);
					try
					{
						if (mFMService != null && !mFMService.isOpen())
						{
							mFMService.openFM();
							setChannelToPlay(digitView.getChannel());
						} else if (mFMService == null)
						{
							try
							{
								// start server
								FMEntryView.this.startService(new Intent("net.kindroid.aidl.service.IFMService"));
								FMEntryView.this.bindService(new Intent("net.kindroid.aidl.service.IFMService"), serviceConnection, Context.BIND_AUTO_CREATE);
							} catch (Exception e)
							{
							}
							try
							{
								Thread.sleep(100);
							} catch (InterruptedException e)
							{
							}
							if (mFMService != null && !mFMService.isOpen())
							{
								mFMService.openFM();
								setChannelToPlay(digitView.getChannel());
							}
						}
						setVolume();
					} catch (Exception e)
					{
					}
				} else
				{
					play.setBackgroundResource(R.drawable.play);
					setEnabled(false);
				}
			}
		}
	};

	/**
	 * judge current head set is on
	 * 
	 * @return
	 */
	private boolean isWiredHeadsetOn()
	{
		boolean result = false;
		AudioManager localAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		if (localAudioManager != null && localAudioManager.isWiredHeadsetOn())
		{
			result = true;
		}

		return result;
	}

	/**
	 * fm service
	 */
	private IFMService mFMService = null;

	/**
	 * fm service connection
	 */
	private ServiceConnection serviceConnection = new ServiceConnection()
	{
		@Override
		public void onServiceDisconnected(ComponentName name)
		{
			mFMService = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			mFMService = IFMService.Stub.asInterface(service);

			if (hasData())
			{
				SharedPreferences settings = FMEntryView.this.getSharedPreferences(FMRADIO_DATA, 0);
				int current = settings.getInt(CHANNEL_VALUE, 1017);
				if (digitView != null)
				{
					try
					{
						if (mFMService != null && !mFMService.isOpen())
						{
							if (!FMService.isMusicVolumeFocus && !isCallState())
							{
								mFMService.openFM();
								play.setBackgroundResource(R.drawable.stop);
								setEnabled(true);
								setChannelToPlay(current);
								setVolume();
							} else
							{
								digitView.setChannel(current);
								updateRedLine(current);
							}
						} else
						{
							digitView.setChannel(current);
							updateRedLine(current);
						}
					} catch (Exception e)
					{
					}
				}
			}
		}

	};

	/**
	 * set current fm volume sync with framework
	 */
	private void setVolume()
	{
		AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		int fm_volume = am.getStreamVolume(AudioManager.STREAM_FM);
		try
		{
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_FM);
			intent.putExtra("state", 1);
			intent.putExtra("speaker", isOutVoice ? 1 : 0);
			sendBroadcast(intent);

			if (mFMService != null)
			{
				mFMService.setVolume(fm_volume);
			}
		} catch (RemoteException e)
		{
		}
	}

	private boolean isCallState()
	{
		TelephonyManager tmgr = (TelephonyManager) getSystemService("phone");
		if (tmgr != null)
		{
			if (tmgr.getCallState() == TelephonyManager.CALL_STATE_RINGING || tmgr.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK)
			{
				return true;
			}
		}
		// if(TelephonyManager.getPhoneCount() > 1)
		// {
		// TelephonyManager tmgr2 = (TelephonyManager)
		// getSystemService("phone1");
		// if (tmgr2 != null)
		// {
		// if(tmgr2.getCallState() == TelephonyManager.CALL_STATE_RINGING ||
		// tmgr2.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK)
		// {
		// return true;
		// }
		// }
		// }
		return false;
	}

	private void testDB()
	{
		ContentResolver resolver = FMEntryView.this.getContentResolver();
		int sq = 875;
		ContentValues values = null;
		// insert
		values = new ContentValues();
		values.put(FMInfo.FMTable.TUNE, sq);
		values.put(FMInfo.FMTable.TITLE, "");
		values.put(FMInfo.FMTable.COMMENT, 0);
		resolver.insert(FMInfo.FMTable.CONTENT_URI, values);
	}
}
